#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 2510

int n, m;
bool dat[maxn][maxn];
int dp[maxn][maxn];
int s1[maxn][maxn];
int s2[maxn][maxn];

void init1(){
	memset(dp, -1, sizeof(dp));
	for (int i = n; i >= 1; i--){
		for (int j = m; j >= 1; j--){
			if (!dat[i][j]){
				s1[i][j] = s1[i][j + 1] + 1;
				s2[i][j] = s2[i + 1][j] + 1;
			}
		}
	}
}

void init2(){
	memset(s1, 0, sizeof(s1));
	memset(s2, 0, sizeof(s2));
	memset(dp, -1, sizeof(dp));
	for (int i = n; i >= 1; i--){
		for (int j = 1; j <= m; j++){
			if (!dat[i][j]){
				s1[i][j] = s1[i][j - 1] + 1;
				s2[i][j] = s2[i + 1][j] + 1;
			}
		}
	}
}

int dfs1(int x, int y){
	if (x>n || y>m || !dat[x][y]) return 0;
	if (dp[x][y] >= 0) return dp[x][y];
	return dp[x][y] = min(dfs1(x + 1, y + 1), min(s1[x][y + 1], s2[x + 1][y])) + 1;
}

int dfs2(int x, int y){
	if (x>n || y>m || !dat[x][y]) return 0;
	if (dp[x][y] >= 0) return dp[x][y];
	return dp[x][y] = min(dfs2(x + 1, y - 1), min(s1[x][y - 1], s2[x + 1][y])) + 1;
}

int getans1(){
	int maxans = 0;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			maxans = max(maxans, dfs1(i, j));
		}
	}
	return maxans;
}

int getans2(){
	int maxans = 0;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			maxans = max(maxans, dfs2(i, j));
		}
	}
	return maxans;
}


int main(){
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> dat[i][j];

	init1();
	int ans1 = getans1();

	init2();
	int ans2 = getans2();

	cout << max(ans1, ans2) << endl;
	return 0;
}